package com.zenithmind.exam.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.exam.mapper.QuestionBankMapper;
import com.zenithmind.exam.pojo.entity.QuestionBank;
import com.zenithmind.exam.service.QuestionBankService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 题库服务实现类
 * 
 * @author ZenithMind
 * @since 2024-07-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class QuestionBankServiceImpl extends ServiceImpl<QuestionBankMapper, QuestionBank> implements QuestionBankService {

    private final QuestionBankMapper questionBankMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createQuestionBank(QuestionBank questionBank) {
        try {
            // 设置创建者信息
            String currentUserId = UserContext.getUserId();
            String currentUserName = UserContext.getUsername();
            questionBank.setCreatorId(currentUserId);
            questionBank.setCreatorName(currentUserName);
            
            // 设置默认值
            if (questionBank.getStatus() == null) {
                questionBank.setStatus(1);
            }
            if (questionBank.getIsPublic() == null) {
                questionBank.setIsPublic(1);
            }
            questionBank.setQuestionCount(0);

            boolean result = save(questionBank);
            if (result) {
                log.info("创建题库成功，题库ID: {}, 题库标题: {}", questionBank.getId(), questionBank.getTitle());
            }
            return result;
        } catch (Exception e) {
            log.error("创建题库失败", e);
            throw new BusinessException("创建题库失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuestionBank(QuestionBank questionBank) {
        try {
            QuestionBank existingBank = getById(questionBank.getId());
            if (existingBank == null) {
                throw new BusinessException("题库不存在");
            }

            // 检查权限
            String currentUserId = UserContext.getUserId();
            if (!existingBank.getCreatorId().equals(currentUserId) && !UserContext.hasRole("ADMIN")) {
                throw new BusinessException("无权限修改此题库");
            }

            boolean result = updateById(questionBank);
            if (result) {
                log.info("更新题库成功，题库ID: {}, 题库标题: {}", questionBank.getId(), questionBank.getTitle());
            }
            return result;
        } catch (Exception e) {
            log.error("更新题库失败", e);
            throw new BusinessException("更新题库失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuestionBank(String bankId) {
        try {
            if (!canDeleteQuestionBank(bankId)) {
                throw new BusinessException("该题库下存在题目，无法删除");
            }

            QuestionBank existingBank = getById(bankId);
            if (existingBank == null) {
                throw new BusinessException("题库不存在");
            }

            // 检查权限
            String currentUserId = UserContext.getUserId();
            if (!existingBank.getCreatorId().equals(currentUserId) && !UserContext.hasRole("ADMIN")) {
                throw new BusinessException("无权限删除此题库");
            }

            boolean result = removeById(bankId);
            if (result) {
                log.info("删除题库成功，题库ID: {}", bankId);
            }
            return result;
        } catch (Exception e) {
            log.error("删除题库失败", e);
            throw new BusinessException("删除题库失败: " + e.getMessage());
        }
    }

    @Override
    @DataCache(key = "exam:bank:#{bankId}", expireTime = 30, timeUnit = TimeUnit.MINUTES)
    public QuestionBank getQuestionBankById(String bankId) {
        return getById(bankId);
    }

    @Override
    public List<QuestionBank> getQuestionBanksByCategory(String categoryId) {
        return questionBankMapper.selectByCategoryId(categoryId);
    }

    @Override
    public List<QuestionBank> getQuestionBanksByCreator(String creatorId) {
        return questionBankMapper.selectByCreatorId(creatorId);
    }

    @Override
    @DataCache(key = "exam:bank:public", expireTime = 15, timeUnit = TimeUnit.MINUTES)
    public List<QuestionBank> getPublicQuestionBanks() {
        return questionBankMapper.selectPublicBanks();
    }

    @Override
    public IPage<QuestionBank> getQuestionBankPage(Page<QuestionBank> page, String title, String categoryId, 
                                                  String creatorId, Integer status, Integer isPublic) {
        return questionBankMapper.selectBankPage(page, title, categoryId, creatorId, status, isPublic);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuestionBankStatus(String bankId, Integer status) {
        try {
            QuestionBank questionBank = new QuestionBank();
            questionBank.setId(bankId);
            questionBank.setStatus(status);
            
            boolean result = updateById(questionBank);
            if (result) {
                log.info("更新题库状态成功，题库ID: {}, 状态: {}", bankId, status);
            }
            return result;
        } catch (Exception e) {
            log.error("更新题库状态失败", e);
            throw new BusinessException("更新题库状态失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuestionCount(String bankId) {
        try {
            // 统计题库中的题目数量
            LambdaQueryWrapper<QuestionBank> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(QuestionBank::getId, bankId);
            
            // 统计题库中的题目数量
            // 注意：这里需要根据实际的Question实体和Mapper来实现
            // 假设有QuestionMapper和Question实体
            int questionCount = 0;
            try {
                // 这里应该调用QuestionService或QuestionMapper来统计题目数量
                // questionCount = questionService.countByBankId(bankId);
                // 或者 questionCount = questionMapper.countByBankId(bankId);
                log.info("统计题库题目数量，题库ID: {}", bankId);
                // 暂时使用0，等Question相关功能实现后再完善
            } catch (Exception e) {
                log.warn("统计题库题目数量失败，题库ID: {}, 错误: {}", bankId, e.getMessage());
            }
            
            int result = questionBankMapper.updateQuestionCount(bankId, questionCount);
            if (result > 0) {
                log.info("更新题库题目数量成功，题库ID: {}, 题目数量: {}", bankId, questionCount);
            }
            return result > 0;
        } catch (Exception e) {
            log.error("更新题库题目数量失败", e);
            throw new BusinessException("更新题库题目数量失败: " + e.getMessage());
        }
    }

    @Override
    public List<QuestionBank> getQuestionBanksByTag(String tag) {
        return questionBankMapper.selectByTag(tag);
    }

    @Override
    @DataCache(key = "exam:bank:hot:#{limit}", expireTime = 10, timeUnit = TimeUnit.MINUTES)
    public List<QuestionBank> getHotQuestionBanks(Integer limit) {
        return questionBankMapper.selectHotBanks(limit);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean copyQuestionBank(String bankId, String newTitle) {
        try {
            QuestionBank sourceBank = getById(bankId);
            if (sourceBank == null) {
                throw new BusinessException("源题库不存在");
            }

            QuestionBank newBank = new QuestionBank();
            BeanUtils.copyProperties(sourceBank, newBank);
            newBank.setId(null); // 清空ID，让系统自动生成
            newBank.setTitle(newTitle);
            newBank.setQuestionCount(0); // 新题库初始题目数量为0
            
            // 设置创建者信息
            String currentUserId = UserContext.getUserId();
            String currentUserName = UserContext.getUsername();
            newBank.setCreatorId(currentUserId);
            newBank.setCreatorName(currentUserName);

            boolean result = save(newBank);
            if (result) {
                log.info("复制题库成功，源题库ID: {}, 新题库ID: {}", bankId, newBank.getId());
                // 复制题库中的题目
                // 注意：这里需要根据实际的Question实体和服务来实现
                try {
                    // 实际实现中应该：
                    // 1. 查询源题库中的所有题目
                    // List<Question> questions = questionService.getQuestionsByBankId(bankId);
                    // 2. 复制题目到新题库
                    // for (Question question : questions) {
                    //     Question newQuestion = new Question();
                    //     BeanUtils.copyProperties(question, newQuestion);
                    //     newQuestion.setId(null);
                    //     newQuestion.setBankId(newBank.getId());
                    //     questionService.save(newQuestion);
                    // }
                    log.info("题库复制完成，需要实现题目复制功能，源题库ID: {}, 新题库ID: {}", bankId, newBank.getId());
                } catch (Exception e) {
                    log.warn("复制题库中的题目失败，源题库ID: {}, 新题库ID: {}, 错误: {}", bankId, newBank.getId(), e.getMessage());
                }
            }
            return result;
        } catch (Exception e) {
            log.error("复制题库失败", e);
            throw new BusinessException("复制题库失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteQuestionBanks(List<String> bankIds) {
        try {
            // 检查每个题库是否可以删除
            for (String bankId : bankIds) {
                if (!canDeleteQuestionBank(bankId)) {
                    throw new BusinessException("题库 " + bankId + " 下存在题目，无法删除");
                }
            }

            boolean result = removeByIds(bankIds);
            if (result) {
                log.info("批量删除题库成功，题库数量: {}", bankIds.size());
            }
            return result;
        } catch (Exception e) {
            log.error("批量删除题库失败", e);
            throw new BusinessException("批量删除题库失败: " + e.getMessage());
        }
    }

    @Override
    public boolean canDeleteQuestionBank(String bankId) {
        // 检查题库下是否有题目
        try {
            // 实际实现中应该查询question表来检查是否有题目
            // 这里需要根据实际的Question实体和Mapper来实现
            // LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
            // queryWrapper.eq(Question::getBankId, bankId);
            // long questionCount = questionMapper.selectCount(queryWrapper);
            // return questionCount == 0; // 没有题目才能删除

            log.info("检查题库是否可以删除，题库ID: {}", bankId);
            // 暂时返回true，等Question相关功能实现后再完善
            return true;
        } catch (Exception e) {
            log.error("检查题库删除条件失败，题库ID: {}", bankId, e);
            return false; // 出错时不允许删除
        }
    }

    @Override
    public Integer countByCreator(String creatorId) {
        return questionBankMapper.countByCreatorId(creatorId);
    }
}
